<?php
/**
 * 功能：框架FUNCTION
 * 说明：function.php
 * 创建日期：2012/7/22
 * 更新日期：
 * 作者：Mirze
 * 补充说明： 
 * 
 */

/**
 * 取得请求的 URI 信息（不含协议、主机名）
 *
 * 例如：  http://qeephp.com/admin/index.php?controller=test
 * 返回： /admin/index.php?controller=test
 *
 * @return string
 */
function get_request_uri()
{
    static $request_uri = null;
    if (!is_null($request_uri)) return $request_uri;

    if (isset($_SERVER['HTTP_X_REWRITE_URL']))
    {
        $request_uri = $_SERVER['HTTP_X_REWRITE_URL'];
    }
    elseif (isset($_SERVER['REQUEST_URI']))
    {
        $request_uri = $_SERVER['REQUEST_URI'];
    }
    elseif (isset($_SERVER['ORIG_PATH_INFO']))
    {
        $request_uri = $_SERVER['ORIG_PATH_INFO'];
        if (!empty($_SERVER['QUERY_STRING']))
        {
            $request_uri .= '?' . $_SERVER['QUERY_STRING'];
        }
    } else {
        $request_uri = '';
    }

    return $request_uri;
}

/**
 * 取得请求的 URI 信息（不含协议、主机名、查询参数、PATHINFO）
 *
 * 例如： 
 * http://qeephp.com/admin/index.php?controller=test
 * http://qeephp.com/admin/index.php/path/to
 *
 * 都返回： 
 * /admin/index.php
 *
 * @return string
 */
function get_request_baseuri()
{
    static $request_base_uri = null;
    if (!is_null($request_base_uri)) return $request_base_uri;

    $uri = get_request_uri();
    $pos = strpos($uri, '?');
    {
        $uri = substr($uri, 0, $pos);
    }
    $pathinfo = get_request_pathinfo();
    $len = strlen($pathinfo);
    if ($len)
    {
        $uri = rtrim($uri, '/');
        if (substr($uri, -$len) == $pathinfo)
        {
            $uri = substr($uri, 0, -$len);
        }
    }
    $request_base_uri = $uri;
    return $uri;
}

/**
 * 取得响应请求的 .php 文件在 URL 中的目录部分
 *
 * 例如： http://qeephp.com/admin/index.php?controller=test
 *
 * 返回：  /admin/
 *
 * @return string
 */
function get_request_dir()
{
    static $dir = null;
    if (!is_null($dir)) return $dir;

    $dir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\') . '/';
    return $dir;
}

/**
 * 返回 PATHINFO 信息
 *
 * 例如： http://qeephp.com/admin/index.php/path/to
 *
 * 返回： /path/to
 *
 * @return string
 */
function get_request_pathinfo()
{
    static $pathinfo = null;
    if (!is_null($pathinfo)) return $pathinfo;

    $pathinfo = get_request_uri();
    $pos = strpos($pathinfo, '?');
    if ($pos !== false)
    {
        $pathinfo = substr($pathinfo, 0, $pos);
    }
    $pathinfo = (string)substr($pathinfo, strlen($_SERVER['SCRIPT_NAME']));
    $pathinfo = rtrim($pathinfo, '/');
    return $pathinfo;
}

/**
 * (功能描述) 世界标准时间:
 *
 * @param int timeZone 时区时差值(8 中国)
 * @return date
 */
function time_standard($timeZone = 8)
{
	return gmdate('Y-m-d H:i:s', time() + 3600 * $timeZone);
}



/**
 * (功能描述)
 *
 * @param 
 * @return
 */
function arr($input, $delimiter = ',')
{
    if (!is_array($input))
    {
        $input = explode($delimiter, $input);
    }
    $input = array_map('trim', $input);
    return array_filter($input, 'strlen');
}

/**
 * (功能描述) 根据生日获取年龄: 
 *
 * @param string $birthday 生日日期：格式2011-07-13
 * @return 0 生日错误
 */
function getAge($birthday){
	$birthday = getDate(strtotime($birthday));  
	$now = getDate();

	$month=0;

	if($now['month'] > $birthday['month']) {
		$month=1;
	}

	if($now['month'] == $birthday['month']) {
		if($now['mday'] >= $birthday['mday']) {
			$month=1;
		}
	}

	return $now['year'] - $birthday['year'] + $month;
}

/**
 * 拷贝目录
 *
 * @param string $source
 * @param string $target
 */
function _copydir($source, $target)
{
	$source = rtrim($source, '/\\') . DS;
	$target = rtrim($target, '/\\') . DS;
	$h = opendir($source);
	$skip = array('.', '..', '.svn', '.cvs');
	while (($file = readdir($h)) !== false)
	{
		if (in_array($file, $skip)) continue;
		$path = $source . $file;
		echo '  create ', $target . $file;
		echo "\n";
		if (is_dir($path))
		{
			mkdir($target . $file, 0777);
			$this->_copydir($path, $target . $file);
		}
		else
		{
			$filesize = filesize($path);
			if ($filesize)
			{
				$fp = fopen($path, 'rb');
				$content = fread($fp, $filesize);
				fclose($fp);
			}
			else
			{
				$content = '';
			}

			$extname = strtolower(pathinfo($path, PATHINFO_EXTENSION));
			if ($extname == 'php' || $extname == 'yaml')
			{
				$content = str_replace($this->content_search, $this->content_replace, $content);
				$content = str_replace(array("\n\r", "\r\n", "\r"), "\n", $content);
			}

			$fp = fopen($target . $file, 'wb');
			fwrite($fp, $content);
			fclose($fp);
			chmod($target . $file, 0666);

			unset($content);
		}
	}
	closedir($h);
}

/** 转换迅雷URL **/
function thunder_url($uri = '')
{
	$result = '';

	if(empty($uri)) {
		return $result;
	}
	
	$urlOdd = explode('//', $uri, 2); //分割成二段
	$head = strtolower($urlOdd); //统一转换小写
	$behind = $urlOdd[1];

	switch($head) {
		case 'thunder:':
			$result = substr(base64_decode($behind), 2, -2);//base64解密，去掉前面的aa和后面zz		
		    break;
		case 'flashget:':
			$temp = explode('&', $behind, 2);
			$result = substr(base64_decode($temp[0]), 10, -10);//base64解密，去掉前面后的[flashget]		
		    break;
		case 'qqdl:':
			$result = base64_decode($behind);//base64解密		
		    break;
		default:
			if($head == "http:"||$head == "ftp:"||$head == "mms:"||$head == "rtsp:"||$head == "https教程:"){
				$result = $uri;//常规地址仅支持http,https,ftp,mms,rtsp传输协议，其他地貌似很少，像xx网盘实际上也是基于base64，但是有的解密了也下载不了
			}
			break;
	}
	return $result;	
}

// URL重定向
function redirect($url, $time=0, $msg='') {
    //多行URL地址支持
    $url = str_replace(array("\n", "\r"), '', $url);
    if (empty($msg))
        $msg = "系统将在{$time}秒之后自动跳转到{$url}！";
    if (!headers_sent()) {
        // redirect
        if (0 === $time) {
            header("Location: " . $url);
        } else {
            header("refresh:{$time};url={$url}");
            echo($msg);
        }
        exit();
    } else {
        $str = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";
        if ($time != 0)
            $str .= $msg;
        exit($str);
    }
}

/**
 +----------------------------------------------------------
 * 产生随机字串，可用来自动生成密码 默认长度6位 字母和数字混合
 +----------------------------------------------------------
 * @param string $len 长度
 * @param string $type 字串类型
 * 0 字母 1 数字 其它 混合
 * @param string $addChars 额外字符
 +----------------------------------------------------------
 * @return string
 +----------------------------------------------------------
 */
function rand_string($len=6,$type='',$addChars='') {
    $str ='';
    switch($type) {
        case 0:
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.$addChars;
            break;
        case 1:
            $chars= str_repeat('0123456789',3);
            break;
        case 2:
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.$addChars;
            break;
        case 3:
            $chars='abcdefghijklmnopqrstuvwxyz'.$addChars;
            break;
        case 4:
            $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借".$addChars;
            break;
        default :
            // 默认去掉了容易混淆的字符oOLl和数字01，要添加请使用addChars参数
            $chars='ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'.$addChars;
            break;
    }
    if($len>10 ) {//位数过长重复字符串一定次数
        $chars= $type==1? str_repeat($chars,$len) : str_repeat($chars,5);
    }
    if($type!=4) {
        $chars   =   str_shuffle($chars);
        $str     =   substr($chars,0,$len);
    }else{
        // 中文随机字
        for($i=0;$i<$len;$i++){
          $str.= msubstr($chars, floor(mt_rand(0,mb_strlen($chars,'utf-8')-1)),1);
        }
    }
    return $str;
}

/**
 +----------------------------------------------------------
 * 字节格式化 把字节数格式为 B K M G T 描述的大小
 +----------------------------------------------------------
 * @return string
 +----------------------------------------------------------
 */
function byte_format($size, $dec=2)
{
	$a = array("B", "KB", "MB", "GB", "TB", "PB");
	$pos = 0;
	while ($size >= 1024) {
		 $size /= 1024;
		   $pos++;
	}
	return round($size,$dec)." ".$a[$pos];
}

/**
 +----------------------------------------------------------
 * 检查字符串是否是UTF8编码
 +----------------------------------------------------------
 * @param string $string 字符串
 +----------------------------------------------------------
 * @return Boolean
 +----------------------------------------------------------
 */
function is_utf8($string)
{
	return preg_match('%^(?:
		 [\x09\x0A\x0D\x20-\x7E]            # ASCII
	   | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
	   |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
	   | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
	   |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
	   |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
	   | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
	   |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
   )*$%xs', $string);
}

//输出安全的html
function filter_html($text, $tags = null){
	$text	=	trim($text);
	//完全过滤注释
	$text	=	preg_replace('/<!--?.*-->/','',$text);
	//完全过滤动态代码
	$text	=	preg_replace('/<\?|\?'.'>/','',$text);
	//完全过滤js
	$text	=	preg_replace('/<script?.*\/script>/','',$text);

	$text	=	str_replace('[','&#091;',$text);
	$text	=	str_replace(']','&#093;',$text);
	$text	=	str_replace('|','&#124;',$text);
	//过滤换行符
	$text	=	preg_replace('/\r?\n/','',$text);
	//br
	$text	=	preg_replace('/<br(\s\/)?'.'>/i','[br]',$text);
	$text	=	preg_replace('/(\[br\]\s*){10,}/i','[br]',$text);
	//过滤危险的属性，如：过滤on事件lang js
	while(preg_match('/(<[^><]+)( lang|on|action|background|codebase|dynsrc|lowsrc)[^><]+/i',$text,$mat)){
		$text=str_replace($mat[0],$mat[1],$text);
	}
	while(preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i',$text,$mat)){
		$text=str_replace($mat[0],$mat[1].$mat[3],$text);
	}
	if(empty($tags)) {
		$tags = 'table|td|th|tr|i|b|u|strong|img|p|br|div|strong|em|ul|ol|li|dl|dd|dt|a';
	}
	//允许的HTML标签
	$text	=	preg_replace('/<('.$tags.')( [^><\[\]]*)>/i','[\1\2]',$text);
	//过滤多余html
	$text	=	preg_replace('/<\/?(html|head|meta|link|base|basefont|body|bgsound|title|style|script|form|iframe|frame|frameset|applet|id|ilayer|layer|name|script|style|xml)[^><]*>/i','',$text);
	//过滤合法的html标签
	while(preg_match('/<([a-z]+)[^><\[\]]*>[^><]*<\/\1>/i',$text,$mat)){
		$text=str_replace($mat[0],str_replace('>',']',str_replace('<','[',$mat[0])),$text);
	}
	//转换引号
	while(preg_match('/(\[[^\[\]]*=\s*)(\"|\')([^\2=\[\]]+)\2([^\[\]]*\])/i',$text,$mat)){
		$text=str_replace($mat[0],$mat[1].'|'.$mat[3].'|'.$mat[4],$text);
	}
	//过滤错误的单个引号
	while(preg_match('/\[[^\[\]]*(\"|\')[^\[\]]*\]/i',$text,$mat)){
		$text=str_replace($mat[0],str_replace($mat[1],'',$mat[0]),$text);
	}
	//转换其它所有不合法的 < >
	$text	=	str_replace('<','&lt;',$text);
	$text	=	str_replace('>','&gt;',$text);
	$text	=	str_replace('"','&quot;',$text);
	 //反转换
	$text	=	str_replace('[','<',$text);
	$text	=	str_replace(']','>',$text);
	$text	=	str_replace('|','"',$text);
	//过滤多余空格
	$text	=	str_replace('  ',' ',$text);
	return $text;
}

/**
 * (功能描述) 错误信息输出
 *
 * @param string $msg 错误信息
 * @param int $flag 错误提示分类
 * @param string $error_type 错误类型
 * @return
 */
function error_msg($msg='', $flag=1, $error_types='')
{
	switch($flag) {
		case '1':
			echo $msg;		
		    break;
		case '2': //创建用户定义错误信息： error_type类型(E_USER_ERROR/E_USER_WARNING/E_USER_NOTICE)
			trigger_error($msg, $error_type);
		    break;
	}
	exit();
}

/** 友好输出 **/
function dump($var, $echo=true,$label=null, $strict=true)
{
	$label = ($label===null) ? '' : rtrim($label) . ' ';
	if(!$strict) {
		if (ini_get('html_errors')) {
			$output = print_r($var, true);
			$output = "<pre>".$label.htmlspecialchars($output,ENT_QUOTES)."</pre>";
		} else {
			$output = $label . " : " . print_r($var, true);
		}
	}else {
		ob_start();
		var_dump($var);
		$output = ob_get_clean();
		if(!extension_loaded('xdebug')) {
			$output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);
			$output = '<pre>'. $label. htmlspecialchars($output, ENT_QUOTES). '</pre>';
		}
	}
	if ($echo) {
		echo($output);
		return null;
	}else
	return $output;
}
?>